import java.util.PriorityQueue;
//我们通过一个类来描述一个任务
class MyTimeTask implements Comparable<MyTimeTask>{
    //此处的time是一个ms级别的时间戳
    private long time;
    //实际任务要执行的代码
    private Runnable runnable;
    public long getTime(){
        return time;
    }
    public void run(){
        runnable.run();
    }
    //参数里面的time是一个相对时间
    public MyTimeTask(Runnable runnable,long time){
        this.runnable=runnable;
        //这里是计算一下真正要执行任务的绝对时间
        this.time=System.currentTimeMillis()+time;
    }

    @Override
    public int compareTo(MyTimeTask o) {
        return (int)(this.time-o.time);
    }
}
//通过这个来来实现一个定时器
class MyTimer{
    //扫描任务的线程
    private Thread t=null;
    //任务队列
    private PriorityQueue<MyTimeTask> queue=new PriorityQueue<>();
    private Object locker=new Object();
    public void schedule(Runnable runnable,long time){
        synchronized (locker){
            MyTimeTask task=new MyTimeTask(runnable,time);
            queue.offer(task);
            locker.notify();
        }
    }
    //构造方法，创建出一个线程，让线程来判断和执行任务
    public MyTimer(){
        t=new Thread(()->{
            //线程需要循环取出队首元素来判断这个元素是不是到时间了
            //如果到了，就执行这个任务，并且将这个任务从队列中删除
            //如果没有到的话，就等待
            while(true){
                synchronized (locker){
                    while(queue.isEmpty()){
                        try {
                            locker.wait();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                    MyTimeTask task=queue.peek();
                    long curTime=System.currentTimeMillis();
                    if(curTime>=task.getTime()){
                        //时间到了就可以执行了
                        task.run();
                        queue.poll();
                    }else{
                        try {
                            locker.wait(task.getTime()-curTime);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
            }
        });
        t.start();
    }
}
public class Test16 {
    public static void main(String[] args) throws InterruptedException {
        MyTimer timer=new MyTimer();
        timer.schedule(()->{
            System.out.println("hello 1000");
        },1000);
        timer.schedule(()->{
            System.out.println("hello 2000");
        },2000);
        timer.schedule(()->{
            System.out.println("hello 3000");
        },3000);
        System.out.println("hello main");


    }
}
